﻿using PLCS.Domain.Processes;
using PLCS.Domain.Solutions;
using PLCS.EntityFrameworkCore.EntityFrameworkCore;
using PLCS.Shared.Common.Constant;

namespace PLCS.EntityFrameworkCore.Solustions
{
    public class SolutionRepository : EfCoreRepository<PLCSDbContext, Solution, Guid>, ISolutionRepository
    {
        public SolutionRepository(IDbContextProvider<PLCSDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public async Task<SolutionStep?> FindSolutionStepAsync(Func<SolutionStep, bool> predicate)
        {
            var dbConext = await GetDbContextAsync();
            return dbConext.SolutionSteps.Where(predicate).FirstOrDefault();
        }

        /// <summary>
        /// 通过方案编号找到方案
        /// </summary>
        /// <param name="solutionNo"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Solution> GetSolutionByNoAsync(string solutionNo)
        {
            var dbConext = await GetDbContextAsync();

            var solution = await FindAsync(x => x.SolutionNo == solutionNo);
            if (solution == null)
                return null;
            solution.SolutionSteps = new List<SolutionStep>();
            if (!solution.SolutionStepStrings.IsNullOrEmpty())
                foreach (var stepNo in solution.SolutionStepStrings.Split(ConstantChar.SplitChar))
                {
                    var step = await dbConext.SolutionSteps.Where(x => x.StepNo == stepNo).FirstOrDefaultAsync();
                    if (step != null)
                    {
                        if (!step.Process.IsNullOrEmpty())
                        {
                            step.Processes = new List<Process>();
                            foreach (var process in step.Process.Split(ConstantChar.SplitChar))
                            {
                                var processEntity = await dbConext.Processes.Where(x => x.ProcessNo == process).FirstOrDefaultAsync();
                                if (processEntity != null)
                                {
                                    if (!processEntity.TriggerStrings.IsNullOrEmpty())
                                    {
                                        if (processEntity.Triggers == null)
                                            processEntity.Triggers = new List<Trigger>();
                                        foreach (var sonItem in processEntity.TriggerStrings.Split(ConstantChar.SplitChar))
                                        {
                                            var trigger = await dbConext.Triggers.Where(x => x.Id.ToString() == sonItem).FirstOrDefaultAsync();
                                            if (trigger == null) continue;
                                            processEntity.Triggers.Add(trigger);
                                        }
                                    }
                                    step.Processes.Add(processEntity);
                                }
                            }
                        }
                        solution.SolutionSteps.Add(step);
                    }
                }
            solution.SolutionSteps.OrderBy(x => x.StepOrder);
            return solution;
        }

        /// <summary>
        /// 找到所有方案
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<IEnumerable<Solution>> GetSolutionListAsync()
        {
            var dbConext = await GetDbContextAsync();

            var solutions = await GetListAsync();

            foreach (var item in solutions)
            {
                item.SolutionSteps = new List<SolutionStep>();
                if (!item.SolutionStepStrings.IsNullOrEmpty())
                    foreach (var stepNo in item.SolutionStepStrings.Split(ConstantChar.SplitChar))
                    {
                        var step = await dbConext.SolutionSteps.Where(x => x.StepNo == stepNo).FirstOrDefaultAsync();
                        if (step != null)
                        {
                            if (!step.Process.IsNullOrEmpty())
                            {
                                step.Processes = new List<Process>();
                                foreach (var process in step.Process.Split(ConstantChar.SplitChar))
                                {
                                    var processEntity = await dbConext.Processes.Where(x => x.ProcessNo == process).FirstOrDefaultAsync();
                                    if (processEntity != null)
                                    {
                                        if (!processEntity.TriggerStrings.IsNullOrEmpty())
                                        {
                                            if (processEntity.Triggers == null)
                                                processEntity.Triggers = new List<Trigger>();
                                            foreach (var sonItem in processEntity.TriggerStrings.Split(ConstantChar.SplitChar))
                                            {
                                                var trigger = await dbConext.Triggers.Where(x => x.Id.ToString() == sonItem).FirstOrDefaultAsync();
                                                if (trigger == null) continue;
                                                processEntity.Triggers.Add(trigger);
                                            }
                                        }
                                    }
                                }
                            }
                            item.SolutionSteps.Add(step);
                        }
                    }
                item.SolutionSteps.OrderBy(x => x.StepOrder);
            }

            return solutions;
        }

        /// <summary>
        /// 找到工步
        /// </summary>
        /// <param name="solutionStepNo"></param>
        /// <returns></returns>
        public async Task<SolutionStep?> GetSolutionStepByNoAsync(string solutionStepNo)
        {
            var dbConext = await GetDbContextAsync();
            return await dbConext.SolutionSteps.SingleOrDefaultAsync(x => x.StepNo == solutionStepNo);
        }

        /// <summary>
        /// 新增工步
        /// </summary>
        /// <param name="stepOrder"></param>
        /// <param name="process"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<SolutionStep> InsertSolutionStepAsync(string stepOrder, string process)
        {
            var dbContext = await GetDbContextAsync();

            var entity = new SolutionStep(stepOrder, process);
            var savedEntity = (await dbContext.Set<SolutionStep>().AddAsync(entity)).Entity;
            await dbContext.SaveChangesAsync();
            return savedEntity;
        }

        /// <summary>
        /// 修改工步
        /// </summary>
        /// <param name="solutionStep"></param>
        /// <returns></returns>
        public async Task<SolutionStep> UpdateSolutionStepAsync(SolutionStep solutionStep)
        {
            var dbContext = await GetDbContextAsync();
            var updatedEntity = dbContext.Update(solutionStep).Entity;
            await dbContext.SaveChangesAsync();
            return updatedEntity;
        }
    }
}